<?php
/*
 * Copyright (c) Taras Kudla, 2010
 */

/*
 * FIXME: Needs to rebuild
 */

final class router extends kernel {

private $map = null;
private $defaultmap = "[f].php?[m]&[a]&[p]";//default router map
private $rules =array(
	"[f]"=>"([A-z0-9-_]{1,100})",		    // runfile
	"[l]"=>"([a-z]{2,3})",			    // language	
	"[a]"=>"([A-z0-9_]{1,255})?", // action
	"[p]"=>"([^'\?]+)?", // parameters
	"[m]"=>"([A-z0-9_]{1,100})" // module
);
/*
 * Parameters separator
 */
private $ps = null;
private $defaultps = "&"; // default value of params separator
private $actionsep = null;
private $defaultactionsep = "&";
private $modsep = null;
private $defaultmodsep = "&";
private $paramseq = null;
private $paramsnext = null;
/*
 * Var names for _GET when _SERVER is disabled
 */
private $getmodvarname = "mod";
private $getactionvarname = "action";
private $getlangvarname = "lang";
public function init(){
	
	$this->map = $this->core->get("routermap");
	# 
	if( $this->map==null){
		$this->map = $this->defaultmap;
	}	
	# detecting parameters eq char and next param char
	if( preg_match("/\[p\:([^A-z0-9_]{1,2})\]/",$this->map,$tmp)){
		$this->paramseq = $tmp[1][0];
		$this->paramsnext = isset($tmp[1][1])?$tmp[1][1]:null;
		$this->map=preg_replace("/\[p\:.+\]/","[p]",$this->map);
	}
	/*
	 * Trying to get params separator
	 */
	if(preg_match("/([^A-z0-9]{1})\[p/i",$this->map,$tmp)){
		$this->ps = $tmp[1];
	} else {
		$this->ps = $this->defaultps;
	}
	if(preg_match("/([^A-z0-9]{1})\[a\]/i",$this->map,$tmp)){
		$this->actionsep = $tmp[1];
	} else {
		$this->actionsep = $this->defaultactionsep;
	}
	if(preg_match("/([^A-z0-9]{1})\[m\]/i",$this->map,$tmp)){
		$this->modsep = $tmp[1];
	} else {
		$this->modsep = $this->defaultmodsep;
	}
}

	# getting default map
	public function getdefaultmap(){
		return $this->defaultmap;
	}


public function parse($link=null){
	
	# replacing all disabled characters
	$map=preg_replace("/(\.|\?|\*|\+|\\\$|\^|\!)/","\\\\$1",$this->map);
	# checking for end [a] symbols
	$map=preg_replace("/a\]([^A-z0-9_]{1})/i","a]\$1?",$map);
	# making parameters separator not required in map
	$map=preg_replace("/(\\".$this->ps.")\[p\]/i","$1?[p]",$map);
	# making module end character not required in map
	$map=preg_replace("/m\]([^A-z0-9_]{1})/i","m]\$1?",$map);
	
	# Checking if $_SERVER is disabled or can use just as _GET Parameters  
	if( !isset($_SERVER["REQUEST_URI"])) {
		# Using _GET mapping 
		$module = ( isset($_GET[$this->getmodvarname]) )? $_GET[$this->getmodgvarname]:null;
		$action = ( isset($_GET[$this->getactionvarname]) )? $_GET[$this->getactionvarname]:null;
		$language = (isset($_GET[$this->getlangvarname])) ? $_GET[$this->getlangvarname]:null;
		$file = null;
		$params = null;
		$this->map = "[f].php?".$this->getmodvarname."=[m]".$this->getactionvarname."=[a]".(($language!=null?"&".$this->getlangvarname."=[l]":null).$this->defaultps."[p]");
	}  
	if( $link!=null || isset($_SERVER["REQUEST_URI"])){
		$query = ($link==null)?$_SERVER["REQUEST_URI"]:$link;
		/*
		 * TODO: url suffix
		 */
    	$urlSuffix = preg_match("/^(?:(http|https):\/\/)?([^\/]+)(.*)/i", null, $tmp);
    	$urlSuffix = isset($tmp[3]) ? $tmp[3] : "/";
    	$query = preg_replace("@^" . $urlSuffix . "@", "", $query);
		if(!$maps = preg_match_all("/\[([a-z]{1})\]/",$map,$tmp)) return false;
		$order=$tmp[0];
		$order = array_combine(array_values($order),array_keys($order));
		$pattern = str_replace( array_keys($this->rules) ,array_values($this->rules) , $map);
		if(!preg_match("@$pattern@",$query,$tmp)){
			return false;
		}
		$action = ( isset($order["[a]"]) && isset($tmp[$order["[a]"]+1]) ? ($tmp[$order["[a]"]+1]) :null);
		$module = ( isset($order["[m]"])? ($tmp[$order["[m]"]+1]) :null);
		$language = ( isset($order["[l]"])? ($tmp[$order["[l]"]+1]) :null);
		$file = ( isset($order["[f]"])? ($tmp[$order["[f]"]+1]) :null);
		$params = ( isset($order["[p]"])? (  isset($tmp[$order["[p]"]+1])?$tmp[$order["[p]"]+1]:null  ) :null);
	}
	$paramsarray = false;
	if( $this->paramsnext!=null){
		$tmparray=explode($this->paramsnext,$params);
	}
	if( $this->paramseq!=null){
		if( !isset($tmparray))$tmparray=explode("&",$params);
		foreach($tmparray as $k=>$v){
			$t=explode($this->paramseq,$v);
			$paramsarray[$t[0]]=(isset($t[1]))?$t[1]:"";
		}
	}	
	return array("module"=>$module,"action"=>$action,"language"=>$language,"runfile"=>$file,"params"=>$params,"paramsarray"=>$paramsarray);
}

public function createlink($module=null,$action=null,$params=null,$runfile=null,$language=null){
	$map = $this->map;
	# modsep replacing if module eq null
	if( $module == null){
		$map = str_replace($this->modsep."[m]","[m]",$map);
		$action = null;
		$params = null;
	}
	# checking if action is 'defaultaction'
	if( $action=="defaultaction")
		$action=null;	
	#ps replacing if params eq null
	if( $params == null){
		$map = str_replace($this->ps."[p]","[p]",$map);
	} else {
		if( $this->paramseq!=null)
			$params = preg_replace("/=/",$this->paramseq,$params);
		if( $this->paramsnext!=null)
			$params = preg_replace("/\&/",$this->paramsnext,$params);
		$params = preg_replace("/([^A-z0-9_])+/","$1",$params);		
	}
	# as replacing if action eq null
	if( $action == null){
		$map = str_replace($this->actionsep."[a]","[a]",$map);
	}
	$link = str_replace(array("[f]","[l]","[a]","[m]","[p]"), 
			array( ($runfile==null?$this->core->get("runfile"):$runfile),
			($language==null?$this->core->get("language"):$language),
			($action==null?null:$action),
			($module==null?null:$module),
			($params==null?null:$params)),
			$map);
	return $this->core->url().$link;
}
}
?>
